package awesome.cpu.gui;

import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;

import javax.swing.JToolTip;

public class GraphToolTip extends JToolTip {
	private static final long serialVersionUID = -986298098308105997L;
	
	private int mComponent = -1;
	
	public GraphToolTip(int component) {
		mComponent = component;
	}
	
	@Override
	public Dimension getPreferredSize() {
		switch (mComponent) {
		case OutputGraph.BRANCH_COND_GATES:
		case OutputGraph.MUX_2WR1:
		case OutputGraph.MEMORY:
		case OutputGraph.MUX_2PC:
		case OutputGraph.MUX_2WD1:
		case OutputGraph.MUXB:
		case OutputGraph.MUX_PC2M:
		case OutputGraph.MUXA:
		case OutputGraph.MUX_2EX:
		case OutputGraph.REGB_SHIFTER:
		case OutputGraph.IMM_SHIFTER:
		case OutputGraph.ALU:
		case OutputGraph.FLAG_REG:
		case OutputGraph.PC:
		case OutputGraph.PCREG:
		case OutputGraph.REGA:
		case OutputGraph.REGB:
		case OutputGraph.REGC:
		case OutputGraph.MR:
		case OutputGraph.ALU_OUT:
		case OutputGraph.OR_GATE:
			return new Dimension(200, 200);
		case OutputGraph.CONTROL:
		case OutputGraph.IR:
		case OutputGraph.REG_FILE:
			return new Dimension(200, 300);
		}
		return new Dimension(10, 10);
	}
	
	@Override
	public void paint(Graphics g) {
		super.paint(g);
		Font font = g.getFont();
		font = new Font(font.getFontName(), font.getStyle(), 10);
		g.setFont(font);
		switch (mComponent) {
		case OutputGraph.BRANCH_COND_GATES:
			g.drawRect(60, 60, 80, 80);
			g.drawLine(100, 60, 100, 35);
			g.drawString("PCWriteCond", 105, 55);
			g.drawLine(60, 100, 35, 100);
			g.drawString("Flag", 35, 95);
			g.drawLine(100, 140, 100, 165);
			g.drawString("Out: BranchCondMet", 50, 170);
			break;
		case OutputGraph.CONTROL:
			g.drawRect(75, 60, 50, 180);
			g.drawLine(75, 70, 35, 70);
			g.drawString("PCWriteCond", 5, 65);
			g.drawLine(75, 90, 35, 90);
			g.drawString("PCWrite", 5, 85);
			g.drawLine(75, 110, 35, 110);
			g.drawString("IorD", 5, 105);
			g.drawLine(75, 130, 35, 130);
			g.drawString("MemRead", 5, 125);
			g.drawLine(75, 150, 35, 150);
			g.drawString("MemWrite", 5, 145);
			g.drawLine(75, 170, 35, 170);
			g.drawString("MemToReg", 5, 165);
			g.drawLine(75, 190, 35, 190);
			g.drawString("IRWrite", 5, 185);
			g.drawLine(75, 210, 35, 210);
			g.drawString("ImmSrc", 5, 205);
			g.drawLine(75, 230, 35, 230);
			g.drawString("PCRegWrite", 5, 225);
			g.drawLine(125, 70, 160, 70);
			g.drawString("FlagWrite", 130, 65);
			g.drawLine(125, 110, 160, 110);
			g.drawString("PCSrc", 130, 105);
			g.drawLine(125, 130, 160, 130);
			g.drawString("ALUSrcA", 130, 125);
			g.drawLine(125, 150, 160, 150);
			g.drawString("ALUSrcB", 130, 145);
			g.drawLine(125, 170, 160, 170);
			g.drawString("ALUOp", 130, 165);
			g.drawLine(125, 190, 160, 190);
			g.drawString("RegWrite", 130, 185);
			g.drawLine(125, 210, 160, 210);
			g.drawString("RegDst", 130, 205);
			g.drawLine(90, 240, 90, 275);
			g.drawString("op", 70, 270);
			g.drawLine(110, 240, 110, 275);
			g.drawString("function", 120, 270);
			break;
		case OutputGraph.MEMORY:
			g.drawRect(60, 60, 80, 80);
			g.drawLine(60, 80, 35, 80);
			g.drawString("Addr", 10, 75);
			g.drawLine(60, 120, 35, 120);
			g.drawString("WriteData", 10, 115);
			g.drawLine(140, 100, 175, 100);
			g.drawString("OutData", 145, 95);
			g.drawLine(80, 60, 80, 25);
			g.drawString("MemRead", 25, 55);
			g.drawLine(120, 60, 120, 25);
			g.drawString("MemWrite", 125, 55);
			break;
		case OutputGraph.IR:
			g.drawRect(55, 60, 50, 180);
			g.drawLine(80, 60, 80, 25);
			g.drawString("IRWrite", 85, 55);
			g.drawLine(55, 150, 20, 150);
			g.drawString("MemData", 5, 145);
			g.drawLine(105, 70, 140, 70);
			g.drawString("op [31~24]", 110, 65);
			g.drawLine(105, 90, 140, 90);
			g.drawString("func [8~5]", 110, 85);
			g.drawLine(105, 110, 140, 110);
			g.drawString("rs1 [23~19]", 110, 105);
			g.drawLine(105, 130, 140, 130);
			g.drawString("rs2 [4~0]", 110, 125);
			g.drawLine(105, 150, 140, 150);
			g.drawString("rd1 [18~14]", 110, 145);
			g.drawLine(105, 170, 140, 170);
			g.drawString("rd2/imm5 [13~9]", 110, 165);
			g.drawLine(105, 190, 140, 190);
			g.drawString("imm24 [23~0]", 110, 185);
			g.drawLine(105, 210, 140, 210);
			g.drawString("imm14 [13~0]", 110, 205);
			g.drawLine(105, 230, 140, 230);
			g.drawString("imm9 [8~0]", 110, 225);
			break;
		case OutputGraph.MUX_2WR1:
			g.drawRect(75, 60, 50, 80);
			g.drawLine(100, 60, 100, 25);
			g.drawString("RegDst", 105, 55);
			g.drawLine(75, 80, 40, 80);
			g.drawString("0 rs2", 30, 75);
			g.drawLine(75, 100, 40, 100);
			g.drawString("1 rd1", 30, 95);
			g.drawLine(75, 120, 40, 120);
			g.drawString("2 30", 30, 115);
			g.drawLine(125, 100, 160, 100);
			g.drawString("Out", 130, 95);
			break;
		case OutputGraph.MUX_2PC:
			g.drawRect(75, 60, 50, 80);
			g.drawLine(100, 60, 100, 25);
			g.drawString("PCSrc", 105, 55);
			g.drawLine(75, 80, 40, 80);
			g.drawString("0 PC+4", 30, 75);
			g.drawLine(75, 100, 40, 100);
			g.drawString("1 Branch", 30, 95);
			g.drawLine(75, 120, 40, 120);
			g.drawString("2 Jump", 30, 115);
			g.drawLine(125, 100, 160, 100);
			g.drawString("Out", 130, 95);
			break;
		case OutputGraph.MUX_2WD1:
			g.drawRect(75, 40, 50, 120);
			g.drawLine(75, 60, 40, 60);
			g.drawString("0 ALUOut", 20, 55);
			g.drawLine(75, 80, 40, 80);
			g.drawString("1 MR", 20, 75);
			g.drawLine(75, 100, 40, 100);
			g.drawString("2 PC", 20, 95);
			g.drawLine(75, 120, 40, 120);
			g.drawString("3 MOVSrc", 20, 115);
			g.drawLine(75, 140, 40, 140);
			g.drawString("4 PCReg", 20, 135);
			g.drawLine(125, 100, 160, 100);
			g.drawString("Out", 130, 95);
			g.drawLine(100, 160, 100, 185);
			g.drawString("MemToReg", 105, 175);
			break;
		case OutputGraph.MUXB:
			g.drawRect(100, 40, 50, 120);
			g.drawLine(125, 40, 125, 25);
			g.drawString("ALUSrcB", 130, 35);
			g.drawLine(100, 60, 65, 60);
			g.drawString("0 B_Shifted", 15, 55);
			g.drawLine(100, 80, 65, 80);
			g.drawString("1 4", 15, 75);
			g.drawLine(100, 100, 65, 100);
			g.drawString("2 imm9<<imm5", 15, 95);
			g.drawLine(100, 120, 65, 120);
			g.drawString("3 Imm24/14", 15, 115);
			g.drawLine(100, 140, 65, 140);
			g.drawString("4 RegB", 15, 135);
			g.drawLine(150, 100, 185, 100);
			g.drawString("Out", 155, 95);
			break;
		case OutputGraph.MUX_PC2M:
			g.drawRect(75, 60, 50, 80);
			g.drawLine(100, 60, 100, 25);
			g.drawString("IorD", 105, 55);
			g.drawLine(75, 80, 40, 80);
			g.drawString("0 PC", 20, 75);
			g.drawLine(75, 120, 40, 120);
			g.drawString("1 ALUOut", 20, 115);
			g.drawLine(125, 100, 160, 100);
			g.drawString("Out", 130, 95);
			break;
		case OutputGraph.MUXA:
			g.drawRect(75, 60, 50, 80);
			g.drawLine(100, 60, 100, 25);
			g.drawString("ALUSrcA", 105, 55);
			g.drawLine(75, 80, 40, 80);
			g.drawString("0 PC", 20, 75);
			g.drawLine(75, 120, 40, 120);
			g.drawString("1 RegA", 20, 115);
			g.drawLine(125, 100, 160, 100);
			g.drawString("Out", 130, 95);
			break;
		case OutputGraph.MUX_2EX:
			g.drawRect(75, 60, 50, 80);
			g.drawLine(75, 80, 40, 80);
			g.drawString("0 imm24", 20, 75);
			g.drawLine(75, 120, 40, 120);
			g.drawString("1 imm14", 20, 115);
			g.drawLine(125, 100, 160, 100);
			g.drawString("Out", 130, 95);
			g.drawLine(100, 140, 100, 175);
			g.drawString("ImmSrc", 105, 165);
			break;
		case OutputGraph.REG_FILE:
			g.drawRect(75, 60, 50, 180);
			g.drawLine(100, 60, 100, 25);
			g.drawString("RegWrite", 105, 55);
			g.drawLine(75, 70, 40, 70);
			g.drawString("ReadReg1", 5, 65);
			g.drawLine(75, 90, 40, 90);
			g.drawString("ReadReg2", 5, 85);
			g.drawLine(75, 110, 40, 110);
			g.drawString("ReadReg3", 5, 105);
			g.drawLine(75, 170, 40, 170);
			g.drawString("WriteReg1", 5, 165);
			g.drawLine(75, 190, 40, 190);
			g.drawString("WriteReg2", 5, 185);
			g.drawLine(75, 210, 40, 210);
			g.drawString("WriteData1", 5, 205);
			g.drawLine(75, 230, 40, 230);
			g.drawString("WriteData2", 5, 225);
			g.drawLine(125, 110, 160, 110);
			g.drawString("RegA", 130, 105);
			g.drawLine(125, 150, 160, 150);
			g.drawString("RegB", 130, 145);
			g.drawLine(125, 190, 160, 190);
			g.drawString("RegC", 130, 185);
			break;
		case OutputGraph.REGB_SHIFTER:
			g.drawRect(75, 60, 50, 80);
			g.drawLine(75, 80, 30, 80);
			g.drawString("RegB", 30, 75);
			g.drawLine(75, 120, 30, 120);
			g.drawString("ShiftCnt", 30, 115);
			g.drawLine(125, 100, 160, 100);
			g.drawString("Out", 130, 95);
			break;
		case OutputGraph.IMM_SHIFTER:
			g.drawRect(75, 60, 50, 80);
			g.drawLine(75, 80, 30, 80);
			g.drawString("imm9", 30, 75);
			g.drawLine(75, 120, 30, 120);
			g.drawString("imm5", 30, 115);
			g.drawLine(125, 100, 160, 100);
			g.drawString("Out", 130, 95);
			break;
		case OutputGraph.ALU:
			g.drawRect(50, 50, 100, 100);
			g.drawLine(50, 80, 25, 80);
			g.drawString("Input1", 10, 75);
			g.drawLine(50, 120, 25, 120);
			g.drawString("Input2", 10, 115);
			g.drawLine(70, 50, 70, 25);
			g.drawString("N", 75, 45);
			g.drawLine(90, 50, 90, 25);
			g.drawString("Z", 95, 45);
			g.drawLine(110, 50, 110, 25);
			g.drawString("C", 115, 45);
			g.drawLine(130, 50, 130, 25);
			g.drawString("V", 135, 45);
			g.drawLine(130, 150, 130, 185);
			g.drawString("ALUOp", 135, 170);
			g.drawLine(150, 95, 185, 95);
			g.drawString("Out: low", 155, 90);
			g.drawLine(150, 105, 185, 105);
			g.drawString("Out: high", 155, 120);
			break;
		case OutputGraph.FLAG_REG:
			g.drawRect(50, 60, 100, 80);
			g.drawLine(50, 100, 25, 100);
			g.drawString("FlagWrite", 5, 95);
			g.drawLine(150, 100, 185, 100);
			g.drawString("Out", 155, 95);
			g.drawLine(70, 140, 70, 175);
			g.drawString("N", 75, 170);
			g.drawLine(90, 140, 90, 175);
			g.drawString("Z", 95, 170);
			g.drawLine(110, 140, 110, 175);
			g.drawString("C", 115, 170);
			g.drawLine(130, 140, 130, 175);
			g.drawString("V", 135, 170);
			break;
		case OutputGraph.PC:
			g.drawRect(50, 50, 100, 100);
			g.drawLine(100, 50, 100, 25);
			g.drawString("PCWriteEnable", 105, 45);
			g.drawLine(50, 100, 25, 100);
			g.drawString("PCIn", 20, 95);
			g.drawLine(150, 100, 175, 100);
			g.drawString("PCOut", 155, 95);
			break;
		case OutputGraph.PCREG:
			g.drawRect(60, 50, 80, 100);
			g.drawLine(100, 50, 100, 25);
			g.drawString("PCRegWrite", 105, 45);
			g.drawLine(60, 100, 35, 100);
			g.drawString("PCRegIn", 10, 95);
			g.drawLine(140, 100, 165, 100);
			g.drawString("PCRegOut", 145, 95);
			break;
		case OutputGraph.REGA:
			g.drawRect(60, 50, 80, 100);
			g.drawLine(60, 100, 35, 100);
			g.drawString("RegAIn", 10, 95);
			g.drawLine(140, 100, 165, 100);
			g.drawString("RegAOut", 145, 95);
			break;
		case OutputGraph.REGB:
			g.drawRect(60, 50, 80, 100);
			g.drawLine(60, 100, 35, 100);
			g.drawString("RegBIn", 10, 95);
			g.drawLine(140, 100, 165, 100);
			g.drawString("RegBOut", 145, 95);
			break;
		case OutputGraph.REGC:
			g.drawRect(60, 50, 80, 100);
			g.drawLine(60, 100, 35, 100);
			g.drawString("RegCIn", 10, 95);
			g.drawLine(140, 100, 165, 100);
			g.drawString("RegCOut", 145, 95);
			break;
		case OutputGraph.MR:
			g.drawRect(60, 50, 80, 100);
			g.drawLine(60, 100, 35, 100);
			g.drawString("MRIn", 10, 95);
			g.drawLine(140, 100, 165, 100);
			g.drawString("MROut", 145, 95);
			break;
		case OutputGraph.ALU_OUT:
			g.drawRect(75, 50, 50, 100);
			g.drawLine(75, 95, 40, 95);
			g.drawString("ALUResult: lo", 5, 90);
			g.drawLine(75, 105, 40, 105);
			g.drawString("ALUResult: hi", 5, 120);
			g.drawLine(125, 95, 160, 95);
			g.drawString("ALUOut: lo", 130, 90);
			g.drawLine(125, 105, 160, 105);
			g.drawString("ALUOut: hi", 130, 120);
			break;
		case OutputGraph.OR_GATE:
			g.drawRect(50, 50, 100, 100);
			g.drawLine(80, 50, 80, 25);
			g.drawString("BranchEnable", 5, 45);
			g.drawLine(120, 50, 120, 25);
			g.drawString("PCWrite", 125, 45);
			g.drawLine(100, 150, 100, 185);
			g.drawString("Out", 105, 180);
			break;
		}
	}
}